<?php
class FormHelper {
	/**
	 * 本表单处理过的数据
	 * @var array
	 */
	var $data;
	
	/**
	 * FormModel实例
	 * @var FormModel
	 */
	var $form_mod = null;
	
	/**
	 * Form的原始配置
	 * @var Form实例
	 */
	var $form;
	
	/**
	 * 本Form对应的表单名称
	 * @var string
	 */
	var $model_name;
	
	/**
	 * 本Form的保存记录的id。即${this->model_name}对应的实例ID
	 * @var string
	 */
	var $id;
	
	/**
	 * 表单所有属性配置的数组列表
	 * @var array
	 */
	var $item_lists; 
	
	/**
	 * 是否支持多语言
	 * @var boolean
	 */
	var $mutil_lan;
	
	/**
	 * 指定ID对应的实体
	 * @var unknown_type
	 */
	var $entity = null;
	
	/**
	 * 当前网站可用语言
	 * @var array
	 */
	var $langs;
	
	/**
	 * 计算出来的组，包含组内属性
	 * @var array
	 */
	var $groups;
	
	private $viewer;
	
	/**
	 * 在获取POST数据时，是否添加网站ID字段
	 * @var boolean
	 */
	var $post_add_site_id = false;
	
	/**
	 * 在获取POST数据时，是否添加当前时间（time()）
	 * @var unknown_type
	 */
	var $post_add_time = false;
	
	public function FormHelper($config){
		$condition = array();
		if(isset($config['site_id'])){
			//如果添加了网站限制时
			$condition['site_id'] = $config['site_id'];
		}
		
		if(isset($config['id'])){
			//通过ID获取值
			$condition['_id'] = $config['id'];
			$this->form = $this->get_mod()->get_by_attrs($condition);
		}elseif (isset($config['name'])){
			//通过form_name获取值
			$condition['name'] = $config['name'];
			$this->form = $this->get_mod()->get_by_attrs($condition);
		}elseif (isset($config['form'])){
			$this->form = $config['form'];
		}
		
		//获取Form对应的实体的ID
		if(isset($config['entity_id'])){
			$this->id = $config['entity_id'];
		}elseif (isset($_REQUEST['id'])){
			$this->id = $_REQUEST['id'];
		}
		
		//保存时是否自动添加当前的site_id
		if(isset($config['add_site_id']) && $config['add_site_id']){
			$this->post_add_site_id = true;
		}

		if(isset($config['post_add_time']) && $config['post_add_time']){
			$this->post_add_time = true;
		}
		
		global $site_info;
		$this->langs = array_keys($site_info['langs']);
		
		//判断是否支持多语言
		if(!$this->form['mutil_lan']){
			$this->mutil_lan = false;
		}else{
			//如果Form支持多语言，只要网站开通多语言即支持多语言
			$this->mutil_lan = count($this->langs)>1;
		}
		
		if(isset($config['model_name'])){
			$this->model_name = $config['model_name'];
		}else{
			//指定模块
			if(!empty($this->form)){
				$this->model_name = $this->form['model'];
			}
		}
		
		global $formHelper;
		$formHelper = $this;
	}
	
	/**
	 * 生成指定的Form HTML
	 */
	public function get_html(){
		$this->init_form_items();
		$this->groups = $this->form['groups'];
		sort_by_rank($this->groups);
		foreach ($this->groups as &$group){
			$group_attrs = $this->sort_group_items($group['items']);
			unset($group['items']);

			//封装进mutil_lan_items、 items内
			foreach ($group_attrs as $attr_name => $attr){
				if($attr['mutil_lan']){
					$group['mutil_lan_items'][$attr_name] = $attr;
				}else{
					$group['items'][$attr_name] = $attr;
				}
			}
		}
		
		$this->init_entity();
		

		//显示
		return $this->get_forms_html();
	}
	
	private function init_entity(){
		if(!empty($this->id) && $this->model_name != null){
			//封装值
			$mod = m($this->model_name);
			$this->entity = $mod->get_by_key($this->id);
		}elseif(isset($_REQUEST['item_id'])){
			$mod = m($this->model_name);
			$this->entity = $mod->get_by_key($_REQUEST['item_id']);
		}
		

		if($this->entity !== null){
			if(isset($_REQUEST['item_id'], $_REQUEST['src_id'])){
				//如果是指定了item_id和src_id
				if($this->form['mutil_lan'] === true && isset($_REQUEST['lang']) && !empty($_REQUEST['lang'])){
					$this->entity = $this->entity[$_REQUEST['src_id']][$_REQUEST['lang']];
					$this->entity = $this->entity[$_REQUEST['item_id']];
				}else{
					$this->entity = $this->entity[$_REQUEST['src_id']][$_REQUEST['item_id']];
				}
			}
				
			//将值附加到属性配置里面
			foreach($this->item_lists as $name=>&$attr){
				if($this->mutil_lan && (isset($attr['mutil_lan']) && $attr['mutil_lan'])){
					//多语言
					foreach($this->langs as $lan){
						if(isset($this->entity[$lan][$name])){
							$attr[$lan]['value'] = $this->entity[$lan][$name];
						}
					}
				}else{
					//单语言
					if(isset($this->entity[$name])){
						$attr['value'] = $this->entity[$name];
					}
				}
			}
		}
	}
	
	private function init_form_items(){
		if($this->item_lists !== null)return;
		$this->item_lists = $this->form['items'];
		//加载属性组内数据
		$group_ids = array();
		foreach ($this->form['attr_groups'] as $group_id => $rank){
			if($group_id === 0)continue;
			$group_ids[] = $group_id;
		}
		if(count($group_ids)>0){
			$attr_mod = new AttrsModel();
			$attrs = $attr_mod->find(array('_id'=>array('$in'=>$group_ids)), 'items');
			foreach ($attrs as $key=>$attr_data){
				$this->item_lists = array_merge($this->item_lists, $attr_data['items']);
			}
		}
	}
	
	private function get_forms_html($mutil_lan=false){
		//查找路径
		$template_file_names = array(
			'forms_' . $this->form['name'] . '.' . TEMPLATE_TYPE,
			'forms.' . TEMPLATE_TYPE,
		);
		$template_path = false;
		foreach($template_file_names as $template_file_name){
			$template_path = self::get_template_path($template_file_name);
			if($template_path!==false)break;
		}
		if($template_path === false)return '未找到表单显示模板！';
	
		if($this->viewer === null){
			$this->viewer = Viewer::get_view();
		}
		$this->viewer->template_dir = $template_path;
		
		$langs = array();
		foreach($this->langs as $lang){
			$langs[$lang] = Lang::get_lan_name($lang);
		}
		$this->viewer->assign('site_langs', $langs);
		
		//初始化当前编辑语言
		$cur_lang = LANGUAGE;
		if(isset($_REQUEST['lang'])){
			$cur_lang = $_REQUEST['lang'];
			//判断是否合法
			if(!Lang::is_site_lang($cur_lang)){
				$cur_lang = LANGUAGE;
			}
		}
		if($this->id!==null){
			$this->viewer->assign('id', $this->id);
		}
		$this->viewer->assign('cur_lang', $cur_lang);
		$this->viewer->assign('attrs', $this->item_lists);
		$this->viewer->assign('groups', $this->groups);
		$this->viewer->assign('langs', $langs);
		$this->viewer->assign('forms', $this->form); //此处修改的话，应该相应修改模板及smarty扩展里面的值
		//$this->viewer->assign('mutil_lan', $mutil_lan);//定义是否开启多语言编辑（以Tab形式出现，一般用于管理后台）
// 		echo $template_file_name;exit;
		$html = $this->viewer->fetch($template_file_name);
		//抽取脚本
		$this->viewer->free();
		return $html;
	}
	
	private function get_template_path($template_name){
		$template_paths = array(
			ROOT_PATH . '/sites/main/' . MAIN_DOMAIN . '/template/data/forms/',	//用户私有模板
			ROOT_PATH . '/protected/includes/forms/template/'					//公共模板
		);
		foreach ($template_paths as $path){
			if(is_file($path . $template_name)){
				return $path;
			}
		}
		return false;
	}
	
	private function sort_group_items($items){
		if(!$this->mutil_lan){
			//如果不支持多语言
			$attr_items = array();
			foreach ($items as $name=>$v){
				$attr_items[$name] = array(
					'name' => $name,
					'mutil_lan' => false,
					'sort' => 1,
				);
			}
			return $attr_items;
		}
		$attr_items = array();
		foreach($items as $attr_name=>$sort){
			if(isset($this->item_lists[$attr_name])){
				$attr_items[$attr_name] = array(
					'name' => $attr_name,
					'mutil_lan' => (isset($this->item_lists[$attr_name]['mutil_lan']) && $this->item_lists[$attr_name]['mutil_lan']),
					'sort' => $sort,
				);
			}
		}
		
		$attr_items = SortHelper::sortByMultiCols($attr_items, array(
			'mutil_lan' => SORT_DESC,
			'sort' => SORT_ASC,
		));
		
		return $attr_items;
	}
	
	/**
	 * 获取FormModel实例
	 */
	private function get_mod(){
		if($this->form_mod === null){
			$this->form_mod = new FormsModel();
		}
		return $this->form_mod;
	}
	
	/**
	 * 获取本表单POST上来的数据
	 */
	public function get_post_data(){
		$this->init_form_items();
		$data = array();
		$test = '';
		foreach ($this->item_lists as $name=>$item){
			$item['id'] = $name;
			$test .= $name . ';';
			$attr_class_name = ucfirst($item['type']) . 'Attr';
			$mutil_lan = null;
			if($this->mutil_lan && $item['mutil_lan']){
				$attr_obj = new $attr_class_name($item, null, true);
				$mutil_lan = $this->mutil_lan;
			}else{
				$attr_obj = new $attr_class_name($item, null, false);
			}
			$attr_obj->formHelper = $this;
			$post_val = $attr_obj->get_post_val($data);
			
			//验证
			$validators = array();
			if(isset($item['validates'])){
				$validators = $this->get_validates($item['validates']);
			}
			if(isset($item['required']) && $item['required']){
				//追加不能为空验证
				$validators = array_merge($validators, $this->get_validates('required'));
			}
			//验证
			if($validators !== null){
				foreach ($validators as $validator_name => $validator){
					$validator->item = $item;
					$validator->mutil_lan = $mutil_lan;
					$validator->langs = $this->langs;
					$result = $validator->validate($post_val);
// 					if($mutil_lan){
// 					}
					
					if($result === false){
						//如果有错误发生
						$attr_obj->error = $validator->get_error() . $attr_class_name;
						break;
					}
				}
			}
			
			if($attr_obj->error!==null){
				//有错误发生
				return array('result'=>false, 'info'=>$attr_obj->error);
			}
		}
		if($this->post_add_site_id && !isset($data['site_id'])){
			$data['site_id'] = SITE_ID;
		}
		
		if($this->post_add_time && !isset($data['time'])){
			$data['time'] = time();
		}
// 		$v = var_export($data, true);
// 		return array('result'=>false, 'info'=>$v);
		return array('result'=>true, 'info'=>'success', 'data'=>$data);
	}
	
	private function get_validates($validates_rules, $params=null){
		$validators = array();
		if(is_string($validates_rules)){
			//获取验证类
			$clazz = null;
			$class_name = ucfirst($validates_rules) . 'Validate';
			$v_file = ROOT_PATH . '/protected/includes/forms/validates/' . $class_name . '.php';
			if(is_file($v_file)){
				require_once $v_file;
				$clazz = new $class_name;
				$clazz->params = $params;
			}
			
			$validators[$validates_rules] = $clazz;
		}elseif (is_array($validates_rules)){
			foreach ($validates_rules as $v_name => $v){
				$validators[$v_name] = $this->get_validates($v_name, $v);
			}
		}
		return $validators;
	}

	/**
	 * 保存Post进来的数据
	 * @param array $data
	 */
	public function save($data=null){
		if($data===null){
			$data = $this->get_post_data();
		}
		if(!$data['result']){
			//有错误发生
			return $data;
		}
		//处理保存逻辑
		$mod = m($this->model_name);
		$id = 0;
		if(isset($_REQUEST['id'])){
			$id = trim($_REQUEST['id']);
		}
		$data = $data['data'];
		if(isset($_REQUEST['src_id'])){
			//如果只是子项
			$src_id = trim($_REQUEST['src_id']);
			$item_id = null;
			if(isset($_REQUEST['item_id'])){
				$item_id = trim($_REQUEST['item_id']);
			}
			if(empty($id)){
				//主表单未保存，保存到temp
				$data['temp_time'] = time();
				
				if(empty($item_id)){
					//新增临时项
					$data['_id'] = gen_guid();
					$mod->insert($data);
				}else{
					//修改临时项
					$mod->update_by_key($item_id, $data);
					$data['_id'] = $item_id;
				}
			}else{
				if(empty($item_id)){
					$item_id = gen_guid();
				}
				//修改，保存到主表单上 
				if(isset($_REQUEST['item_lang']) && !empty($_REQUEST['item_lang'])){
					$lang = $_REQUEST['item_lang'];
					$mod->update_by_key($id, array($src_id . '.' . $lang . '.' . $item_id=>$data));
					$data['_id'] = $item_id;
				}else{
					$mod->update_by_key($id, array($src_id . '.' . $item_id=>$data));
					$data['_id'] = $item_id;
// 		$v = var_export($data, true);
// 		return array('result'=>false, 'info'=>$id .'==>'. $src_id . '.' . $item_id . $this->model_name);
				}
			}
			return array('result'=>true, 'info'=>Lang::get('success'), 'data'=>$data);
		}else{
			if(empty($id)){
				//新增
				$mod->insert($data);
			}else{
				//修改
				$old_obj = $mod->get_by_key($id);
				$data = array_merge($old_obj, $data);
				$mod->update_by_key($id, $data);
			}
		}
		return array('result'=>true, 'info'=>Lang::get('success'), 'data'=>$data);
	}

// 	/**
// 	 * 格式化好用于列表显示的数据结构
// 	 */
// 	public function get_list_view_data(){
// 		if(!isset($this->forms['list_view'])){
// 			//如果没有设置有列表显示字段时
// 			return null;
// 		}
// 		$list_views =  $this->forms['list_view'];
// 		$attrs = self::get_form_items();
// 		$list_view_title = array();
// 		foreach($list_views as $list_field=>$sort_data){
// 			$list_view_title['title'][$list_field] = $attrs[$list_field][$this->lang]['name'];
// 		}
// 		return $list_view_title;
// 	}
}

?>